<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>Babylon.js + nipplejs 虚拟摇杆演示</title>
    <style>
        html,
        body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            touch-action: none;
        }

        #renderCanvas {
            width: 100%;
            height: 100%;
            display: block;
        }

        /* 横屏模式下的样式 */
        @media screen and (orientation: landscape) {
            #renderCanvas {
                width: 100vw;
                height: 100vh;
            }
        }

        /* 竖屏模式下的提示界面 */
        #portraitWarning {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            z-index: 10000;
            color: white;
            font-family: Arial, sans-serif;
            text-align: center;
            justify-content: center;
            align-items: center;
            flex-direction: column;
        }

        #portraitWarning.visible {
            display: flex;
        }

        .rotate-icon {
            font-size: 4em;
            margin-bottom: 20px;
            animation: rotate 2s infinite ease-in-out;
        }

        @keyframes rotate {
            0% {
                transform: rotate(0deg);
            }

            50% {
                transform: rotate(90deg);
            }

            100% {
                transform: rotate(90deg);
            }
        }

        .warning-text {
            font-size: 1.5em;
            margin-bottom: 10px;
        }

        .hint-text {
            font-size: 1em;
            opacity: 0.8;
        }

        /* 摇杆容器样式 */
        .joystick-container {
            position: absolute;
            bottom: 30px;
            width: 150px;
            height: 150px;
            z-index: 1000;
        }

        #leftJoystick {
            left: 30px;
        }

        #rightJoystick {
            right: 30px;
        }

        /* 摇杆区域样式 */
        .joystick-zone {
            width: 100%;
            height: 100%;
            background-color: rgba(255, 255, 255, 0.3);
            border-radius: 50%;
            border: 2px solid rgba(255, 255, 255, 0.5);
        }

        /* 横屏锁定时的样式调整 */
        @media screen and (orientation: portrait) {
            .joystick-container {
                bottom: 20px;
                width: 120px;
                height: 120px;
            }

            #leftJoystick {
                left: 20px;
            }

            #rightJoystick {
                right: 20px;
            }
        }

        .left-value {
            position: fixed;
            bottom: 200px;
            left: 20px;
            color: gold;
            font-size: 30px;
        }

        .right-value {
            position: fixed;
            bottom: 200px;
            right: 20px;
            color: gold;
            font-size: 30px;
        }
    </style>
</head>

<body>
    <!-- 竖屏提示界面 -->
    <div id="portraitWarning" class="visible">
        <div class="rotate-icon">🔄</div>
        <div class="warning-text">请将设备横屏使用</div>
        <div class="hint-text">为了更好的游戏体验，请旋转您的设备</div>
    </div>

    <!-- 3D场景画布 -->
    <canvas id="renderCanvas"></canvas>

    <!-- 虚拟摇杆容器 -->
    <div id="leftJoystick" class="joystick-container">
        <div id="leftZone" class="joystick-zone"></div>
    </div>
    <div id="rightJoystick" class="joystick-container">
        <div id="rightZone" class="joystick-zone"></div>
    </div>

    <!-- 打印摇杆值 -->
    <div id="app">
        <div class="left-value">{{leftValue}}</div>
        <div class="right-value">{{rightValue}}</div>
    </div>

    <!-- 引入所需库 -->
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/nipplejs@latest/dist/nipplejs.min.js"></script>

    <script src="../../libs/vue.min.js"></script>

    <script>
        //初始化页面
        var app = new Vue({
            el: '#app',
            data: function () {
                return {
                    leftValue: 'x:0 y:0',
                    rightValue: 'x:0 y:0',
                }
            },
            methods: {}
        });

        // 屏幕方向管理
        class ScreenOrientationManager {
            constructor() {
                this.portraitWarning = document.getElementById('portraitWarning');
                this.renderCanvas = document.getElementById('renderCanvas');
                this.isLandscape = false;

                this.init();
            }

            init() {
                // 检测初始方向
                this.checkOrientation();

                // 监听方向变化
                window.addEventListener('orientationchange', () => {
                    setTimeout(() => this.checkOrientation(), 100);
                });

                // 监听窗口大小变化（备用）
                window.addEventListener('resize', () => {
                    this.checkOrientation();
                });
            }

            checkOrientation() {
                // 检测是否为横屏
                const isLandscape = window.innerWidth > window.innerHeight;

                if (isLandscape) {
                    this.showLandscapeMode();
                } else {
                    this.showPortraitWarning();
                }
            }

            showLandscapeMode() {
                this.portraitWarning.classList.remove('visible');
                this.renderCanvas.style.display = 'block';
                this.isLandscape = true;

                // 触发resize事件确保Babylon.js正确调整大小
                setTimeout(() => {
                    if (window.engine) {
                        window.engine.resize();
                    }
                }, 300);
            }

            showPortraitWarning() {
                this.portraitWarning.classList.add('visible');
                this.renderCanvas.style.display = 'none';
                this.isLandscape = false;

                // 取消强制横屏
                this.portraitWarning.classList.remove('visible');
                this.renderCanvas.style.display = 'block';
                this.isLandscape = true;
                // 触发resize事件确保Babylon.js正确调整大小
                setTimeout(() => {
                    if (window.engine) {
                        window.engine.resize();
                    }
                }, 300);
            }

            // 强制横屏（需要用户交互触发）
            requestLandscape() {
                if (screen.orientation && screen.orientation.lock) {
                    screen.orientation.lock('landscape').catch(() => {
                        console.log('屏幕方向锁定失败，显示提示界面');
                    });
                }
            }
        }

        // 初始化屏幕方向管理
        const orientationManager = new ScreenOrientationManager();

        // 初始化3D场景
        const initScene = () => {
            // 只有在横屏模式下才初始化场景
            if (!orientationManager.isLandscape) {
                setTimeout(initScene, 500);
                return;
            }

            const canvas = document.getElementById('renderCanvas');
            const engine = new BABYLON.Engine(canvas, true);
            const scene = new BABYLON.Scene(engine);

            // 存储引擎引用供方向管理使用
            window.engine = engine;

            // 创建相机
            const camera = new BABYLON.ArcRotateCamera(
                "camera",
                -Math.PI / 2,
                Math.PI / 2.5,
                10,
                BABYLON.Vector3.Zero(),
                scene
            );

            // 设置相机角度限制
            camera.upperBetaLimit = Math.PI / 2.2;
            camera.lowerBetaLimit = 0.1;

            // 清除相机默认输入控制
            camera.inputs.clear();

            // 创建光源
            new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);

            // 创建可控制的盒子
            const box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, scene);
            box.position.y = 0.5;

            // 创建地面
            const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 10, height: 10 }, scene);
            const groundMaterial = new BABYLON.StandardMaterial("groundMat", scene);
            groundMaterial.diffuseColor = new BABYLON.Color3(0.5, 0.8, 0.5);
            ground.material = groundMaterial;

            // 初始化变量
            let boxVelocity = new BABYLON.Vector3(0, 0, 0);
            const moveSpeed = 0.05;
            const rotationSpeed = 0.005;

            // 右摇杆旋转控制变量
            let rightJoystickVector = { x: 0, y: 0 };
            let isRightJoystickActive = false;

            // 创建左摇杆（控制移动）
            const leftManager = nipplejs.create({
                zone: document.getElementById('leftZone'),
                mode: 'static',
                position: { left: '50%', top: '50%' },
                color: 'blue',
                size: 120
            });

            // 创建右摇杆（控制旋转）
            const rightManager = nipplejs.create({
                zone: document.getElementById('rightZone'),
                mode: 'static',
                position: { left: '50%', top: '50%' },
                color: 'red',
                size: 120
            });

            // 监听左摇杆移动事件
            leftManager.on('move', function (evt, data) {
                console.log('左摇杆移动:', JSON.stringify(data.vector));
                app.leftValue = 'x:' + data.vector.x.toFixed(2) + ' y:' + data.vector.y.toFixed(2);
                boxVelocity.x = data.vector.x * moveSpeed;
                boxVelocity.z = data.vector.y * moveSpeed;
            });

            // 左摇杆释放时停止移动
            leftManager.on('end', function () {
                console.log('左摇杆停止');
                app.leftValue = 'x:0 y:0';
                boxVelocity.x = 0;
                boxVelocity.z = 0;
            });

            // 监听右摇杆事件
            rightManager.on('start', function () {
                isRightJoystickActive = true;
            });

            rightManager.on('move', function (evt, data) {
                console.log('右摇杆移动:', JSON.stringify(data.vector));
                app.rightValue = 'x:' + data.vector.x.toFixed(2) + ' y:' + data.vector.y.toFixed(2);
                rightJoystickVector.x = data.vector.x;
                rightJoystickVector.y = data.vector.y;
                isRightJoystickActive = true;
            });

            rightManager.on('end', function () {
                console.log('右摇杆停止');
                app.rightValue = 'x:0 y:0';
                rightJoystickVector.x = 0;
                rightJoystickVector.y = 0;
                isRightJoystickActive = false;
            });

            // 场景渲染循环
            scene.registerBeforeRender(function () {
                box.position.addInPlace(boxVelocity);

                // 限制盒子不超出地面边界
                box.position.x = Math.max(-4.5, Math.min(4.5, box.position.x));
                box.position.z = Math.max(-4.5, Math.min(4.5, box.position.z));

                // 持续应用右摇杆旋转
                if (isRightJoystickActive) {
                    camera.alpha -= rightJoystickVector.x * rotationSpeed;
                    camera.beta -= rightJoystickVector.y * rotationSpeed;
                }
            });

            // 响应窗口大小变化
            window.addEventListener('resize', function () {
                if (orientationManager.isLandscape) {
                    engine.resize();
                }
            });

            // 启动渲染循环
            engine.runRenderLoop(function () {
                scene.render();
            });
        };

        // 在用户交互后尝试初始化场景
        document.addEventListener('click', function () {
            if (!window.engine) {
                initScene();
            }
        }, { once: true });

        // 页面加载后初始化
        window.addEventListener('load', initScene);
    </script>
</body>

</html>